#pragma once
#include <iostream>
#include <string>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Common.hpp"

class Epoller
{
public:
    Epoller()
        : _epfd(-1)
    {
        _epfd = epoll_create(256);
        if (_epfd == -1)
        {
            LOG(LogLevel::FATAL) << "epoll_create erro";
            exit(EPOLL_CREATE_ERRO);
        }
        LOG(LogLevel::DEBUG) << "_epfd: " << _epfd;
    }
    void EventHelper(int sockfd,uint32_t events,int op)
    {
        struct epoll_event ep;
        ep.data.fd = sockfd;
        ep.events = events;
        int n = epoll_ctl(_epfd,EPOLL_CTL_ADD,sockfd,&ep);
        if(n == -1)
        {
            LOG(LogLevel::WARNING) << "epoll_ctl erro";
        }
        else
        {
            LOG(LogLevel::DEBUG) << "epoll_ctl success,sockfd: " << sockfd;
        } 
    }
    void AddEvent(int sockfd,uint32_t events)
    {
        EventHelper(sockfd,events,EPOLL_CTL_ADD);
    }
    void DeleteEvent(int sockfd)
    {
        int n = epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);
        if(n == -1)
        {
            LOG(LogLevel::WARNING) << " epoll_ctl_del erro";
            return;
        }
        LOG(LogLevel::DEBUG) << "epoll_ctl_del success";
    }
    void ModifyEvent(int sockfd,uint32_t events)
    {
        EventHelper(sockfd,events,EPOLL_CTL_MOD);
    }
    int WaitEvent(struct epoll_event revs[], int maxnum, int timeout)
    {
        int n = epoll_wait(_epfd,revs,maxnum,timeout);
        if (n < 0)
        {
            LOG(LogLevel::WARNING) << "epoll_wait error";
        }
        else if (n == 0)
        {
            LOG(LogLevel::WARNING) << "epoll_wait timeout";
        }
        else
        {
            // TODO
        }

        return n;
    }
    ~Epoller() 
    {
        close(_epfd);
    }

private:
    int _epfd;
};